using Kopernikus.Parsing.GenericLexing;
using Kopernikus.Parsing.GenericParsing;
using Kopernikus.Parsing.Lexing;
using NUnit.Framework;

namespace Kopernikus.Parsing.Tests.GenericParsing
{
    [TestFixture]
    public class TestNullableGrammars
    {
        public class P
        {
            [CfgStart("P -> A B C")]
            private static string p_main(string[] args)
            {
                return string.Join(",", args);
            }

            [Cfg("A ->")]
            [Cfg("BB ->")]
            [Cfg("C ->")]
            private static string p_null()
            {
                return "(null)";
            }

            [Cfg("A -> a")]
            [Cfg("B -> BB")]
            [Cfg("BB -> b")]
            [Cfg("C -> c")]
            private static string p_ABC(string[] args)
            {
                return args[0];
            }

            [LexDefault(LexDefaultAttributeOptions.AnySingleCharacter)]
            private static string t_default(LexerMatch m)
            {
                return m.Value;
            }
        }

        [Test]
        public void Test()
        {
            GenericParser<P, string> parser = GenericParser<P, string>.Create(new P());

            Assert.AreEqual("(null),(null),(null)", parser.Parse(""));
            Assert.AreEqual("a,b,c", parser.Parse("abc"));

            Assert.AreEqual("a,(null),(null)", parser.Parse("a"));
            Assert.AreEqual("(null),b,(null)", parser.Parse("b"));
            Assert.AreEqual("(null),(null),c", parser.Parse("c"));

            Assert.AreEqual("(null),b,c", parser.Parse("bc"));
            Assert.AreEqual("a,(null),c", parser.Parse("ac"));
            Assert.AreEqual("a,b,(null)", parser.Parse("ab"));
        }
    }
}